import { history } from 'umi';
import { extend, RequestOptionsInit } from 'umi-request';
import { Request } from '@bingo/request';
import { Modal, message } from 'antd';
import isEmpty from 'lodash/isEmpty';
import { getCookie, removeCookie } from './cookie';

export interface IRequestOptions extends RequestOptionsInit {
  /** 显示message弹窗 */
  showMessage?: boolean;
  /** 显示modal弹窗 */
  showModal?: boolean;
  /** 仅返回content数据体 */
  onlyContent?: boolean;
  /** 仅返回请求响应状态，true为成功，false为失败 */
  onlyStatus?: boolean;
}

export interface IRequestOptionsExt extends IRequestOptions {
  url: string;
  method: string;
  data: object;
  customParams?: object;
}

interface IResponseError<D = any> extends Error {
  name: string;
  data: D;
  response: Response;
}

/**
 * 网络异常处理，未得到服务器响应或请求超时
 * @param error
 */
const errorHandler = (error: IResponseError) => {
  const { response = {} as Response } = error;
  const { status = '' } = response || {};
  console.error(`服务器响应异常 ${status}`);
  message.error(`服务器响应异常 ${status}`, 2);
};

/**
 * 需要重新登录的code
 */
const authorityFailureCodes = [
  '120001',
  '120002',
  '120003',
  '120010',
  '10020302',
  '10020301',
];

/**
 * request原始对象
 */
const request = extend({
  timeout: 60000,
  requestType: 'json',
  errorHandler,
});

// 全局请求拦截器
request.interceptors.request.use(
  (url: string, tempOptions: IRequestOptions) => {
    // 组装请求配置
    const options = {
      showMessage: true,
      onlyContent: true,
      ...tempOptions,
      headers: {
        token: getCookie('token'),
        sid: getCookie('sid'),
      },
    };
    return { url, options };
  },
);

// 全局响应拦截器，克隆响应对象做解析处理
request.interceptors.response.use(
  async (originResponse, options: IRequestOptions) => {
    const response = await originResponse.clone().json();
    const { content, errorCode, errorMsg, status } = response;
    // 需要重新登录的错误码
    if (authorityFailureCodes.includes(errorCode)) {
      removeCookie('token');
      history.replace('/login');
    }
    if (status === 'SUCCESS' && options.onlyStatus && isEmpty(content)) {
      return true;
    }
    if (status === 'SUCCESS' && options.onlyContent) {
      return content;
    }
    if (status === 'ERROR' && options.showMessage) {
      message.error(errorMsg, 1);
      return undefined;
    }
    if (status === 'ERROR' && options.showModal) {
      Modal.error({ title: '请求错误', content: errorMsg, centered: true });
      return undefined;
    }
    return response;
  },
);

const http = new Request((options: IRequestOptionsExt) => {
  const { url, method, data, customParams = {} } = options;
  return request(url, {
    prefix: API_HOST,
    method,
    data,
    ...customParams,
  });
});

export function get<T>(
  url: string,
  data?: object,
  requestOptions?: IRequestOptions,
) {
  return http.get<T>(url, data, (options: IRequestOptions) => {
    options.customParams = requestOptions ?? {};
    return options;
  });
}

export function post<T>(
  url: string,
  data?: object,
  requestOptions?: IRequestOptions,
) {
  return http.post<T>(
    url,
    data,
    (options: IRequestOptions) => {
      options.customParams = requestOptions ?? {};
      return options;
    },
    requestOptions!?.contentType
      ? { contentType: requestOptions!.contentType }
      : {},
  ); // 解决umi-request需要自己构建formData
}

// export default http;
